package com.hs.egova.aop;

import com.hs.egova.anno.SysLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 定义注解AOP，执行统一操作
 * @author husheng
 * @version v1.0
 * @date 2021/7/20 13:51
 * @email husheng@egova.com.cn
 */
//@Component
@Aspect
@Slf4j
public class SysLogAspect {

    /**
     * 通过注解的形式找到切面
     * 也可以通过切点表达式
     */
    @Pointcut("@annotation(com.hs.egova.anno.SysLog)")
    public void pointcut() {

    }


    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long time = System.currentTimeMillis() - beginTime;
        /**
         * 进行日志保存等操作
         */
        savaLog(point, time);
        return result;
    }

    /**
     *
     * @param point
     * @param time
     */
    private void savaLog(ProceedingJoinPoint point, long time) {
        //通过切点反射获取函数签名
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        SysLog sysLog = method.getAnnotation(SysLog.class);
        if (sysLog != null) {
            //注解上的描述
            log.info(sysLog.value());
        }
        //请求的类名、方法名
        String className = point.getTarget().getClass().getName();
        String methodName = signature.getName();
        log.info("类名：{}", className);
        log.info("方法名: {}", methodName);
        //请求参数等
        //Object[] args = point.getArgs();
    }
}
